package com.suntine.familytree.core.framework.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;

/**
 * @corporation 
 * @author suntine
 * @creation 2011-4-14 上午11:28:06
 * @description 
 */
public abstract class BaseDaoJpaImpl<T extends Serializable> implements BaseDao<T>{
	
	@PersistenceContext
	private EntityManager em;
	private Class<T> persistentClass;
	protected transient Logger logger ;
	public BaseDaoJpaImpl()
	{
		super();
		//suntine:不设置 proxy-target-class="true" 的话 可以用下面方式 获取 泛型参数的实际类
		this.persistentClass = ((Class)((java.lang.reflect.ParameterizedType)super.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
		
	}
	
	public void initLogger(Class clazz){
		logger = Logger.getLogger(clazz);;
	}
	
	protected Class<T> getPersistentClass() {
		return this.persistentClass;
	}
	  
	@Override
	public T save(T entity) {
		// TODO Auto-generated method stub
		em.persist(entity);
		return null;
	}

	@Override
	public int delete(T entity) {
		// TODO Auto-generated method stub
		em.remove(entity);
		return 0;
	}

	@Override
	public T findById(long id) {
		// TODO Auto-generated method stub
		em.find(getPersistentClass(), id);
		return null;
	}

	@Override
	public int update(T entity) {
		// TODO Auto-generated method stub
		em.merge(entity);
		return 0;
	}
	
	
	//@Transactional
	public List queryByJpql(String jpql) {

		List result = new ArrayList();
		Query q = em.createQuery(jpql);
		result = q.getResultList();
		result.size();
		return result;
		
	};
	
	//@Transactional 
	//不配置Service的事务的话为什么Dao这里必须加事务呢？
	//也就是说EntityManager的查询操作必须有事务？不然就查过后就Close了，
	//继而再引用查出的List就报：
	//org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed
	//所以这就可以验证系统的声明式事务是否配置成功
	public List queryAll(){
		
		List result = new ArrayList();
		Query q = em.createQuery("select e from "+getPersistentClass().getName()+" e");
		result = q.getResultList();
		
		//result.size(); // suntine:lazy load 不过注释掉这一行，无影响，DN难道改进了么？Transactional貌似是必须的，不然就报Object Manager has been closed 
		
		return result;
		
	}
}
